#############################################################################################
#############################################################################################
# 
#   Open Source License/Disclaimer, Forecast Systems Laboratory NOAA/OAR/GSD, 
#   325 Broadway Boulder, CO 80305
#
#   This software is distributed under the Open Source Definition, which may be 
#   found at http://www.opensource.org/.
#   In particular, redistribution and use in source and binary forms, with or 
#   without modification, are permitted provided that the following conditions are met:
#
#   - Redistributions of source code must retain this notice, this list of 
#     conditions and the following disclaimer.
#
#   - Redistributions in binary form must provide access to this notice, this 
#     list of conditions and the following disclaimer, and the underlying source code.
#
#   - All modifications to this software must be clearly documented, and are 
#     solely the responsibility of the agent making the modifications.
#
#   - If significant modifications or enhancements are made to this software, 
#     the GSD Software Policy Manager (softwaremgr.fsl@noaa.gov) should be notified.
#
#   THIS SOFTWARE AND ITS DOCUMENTATION ARE IN THE PUBLIC DOMAIN AND ARE 
#   FURNISHED "AS IS." THE AUTHORS, THE UNITED STATES GOVERNMENT, ITS INSTRUMENTALITIES,
#   OFFICERS, EMPLOYEES, AND AGENTS MAKE NO WARRANTY, EXPRESS OR IMPLIED, AS TO
#   THE USEFULNESS OF THE SOFTWARE AND DOCUMENTATION FOR ANY PURPOSE. THEY ASSUME 
#   NO RESPONSIBILITY (1) FOR THE USE OF THE SOFTWARE AND DOCUMENTATION; OR (2) TO PROVIDE
#   TECHNICAL SUPPORT TO USERS. 
#############################################################################################
#############################################################################################


import inspect
import numpy as np

# Import the EnsembleGeneratorClass
from .ensemble_generator_class import EnsembleGeneratorClass

# Import Shallow Water Model library from cdar model
from ..models.ShallowWaterModel.ShallowWater2DModel import ShallowWater2DModel as model

class cdar_ensemble(EnsembleGeneratorClass):
    def __init__(self):
        # RETURNS:
        #    EnsArray = (3*Ntimesteps)x(EnSize) numpy array. Column is 
        #               (S(t0), I(t0), S(t1), I(t1), ..., S(tN), I(tN))^T
        #    EnsTime = Ntimsteps numpy vector of time
        self.Name = 'Deterministic Model'

    def fwd_propagate(self,Param,start_time,stop_time,Ntimestep):
        # Initialization includes the parameter array, start time, stop time, and the number of timesteps
        # Param = (EnSize)x(4) Numpy array of ensemble member parameters
        #              <S0>\t<I0>\t<beta>\t<mu>
        EnSize = Param.shape[0]
        EnsTime = np.linspace(start_time,stop_time,Ntimestep)

        # Define empty array to append ensemble members to
        EnsArray = np.zeros((3*Ntimestep,EnSize))

        # Generate each of the ensemble members
        for i in range(EnSize):
            # Read file ICs to variable names
            S0 = Param[i,0]
            I0 = Param[i,1]
            beta = Param[i,2]
            mu = Param[i,3]

            # Initial Conditions
            y0 = np.array([[S0],[I0]])
            model.init
 
            # Simulate Shallow Water Model
            Xsim = model.SIRode(y0, EnsTime, beta, mu)
            Xsim = Xsim.transpose()

            # Reshape and write to EnsArray.
            EnsArray[:,i] = Xsim.reshape(3*Ntimestep)

        return [EnsArray,EnsTime]

